package parser;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import interpreter.AssignmentInst;
import interpreter.CollectInst;
import interpreter.HeapAnalyzeInst;
import interpreter.Instruction;
import interpreter.PrintInst;
import interpreter.SDeclaration;
import interpreter.TDeclaration;

public class Parser {
	
	private static final String STRING_CONSTANT = "[A-Za-z][A-Za-z0-9]*";
	private static final String QUOTES = "^\"(.+)\"$";
	
	public static Instruction parse(String line) throws Exception {
		
		Instruction instruction = null;
		Pattern pattern;
		Matcher matcher;
		
		if(line.startsWith("Print")){
			pattern = Pattern.compile("^Print (.+)$"); 
			matcher = pattern.matcher(line);
			
			if (matcher.matches()){
				String value = matcher.group(1);
				Pattern patternTmp = Pattern.compile(QUOTES);
				Matcher matcherTmp = patternTmp.matcher(matcher.group(1));
				if (matcherTmp.matches()){
					//constant-string
					instruction = new PrintInst(matcherTmp.group(1),true);
				}else{
					instruction = new PrintInst(value,false);
				}
			}else{
				throw new Exception("Error near Print");
			}
			
		}else if(line.startsWith("VarDeclS")){
			
			pattern = Pattern.compile("^VarDeclS ("+STRING_CONSTANT+") (\".*\"|NULL"+")$"); 
			matcher = pattern.matcher(line);
			
			if (matcher.matches()){
				
				String varName = matcher.group(1);
				String value  = matcher.group(2);
				if (value.equals("NULL")){
					instruction = new SDeclaration(varName, value);					
				}else{
					Pattern patternTmp = Pattern.compile(QUOTES);
					Matcher matcherTmp = patternTmp.matcher(value);
					if (matcherTmp.matches()){
						//constant-string
						instruction = new SDeclaration(varName, matcherTmp.group(1));
					}else{
						throw new Exception("Quotes missing");
					}					
				}
			}else{
				throw new Exception("Error near VarDeclS");
			}
			
		}else if(line.startsWith("VarDeclT")){
			pattern = Pattern.compile("^VarDeclT (.+)$"); 
			matcher = pattern.matcher(line);
			
			if (matcher.matches()){
				String varName = matcher.group(1);
				Pattern patternTmp = Pattern.compile(STRING_CONSTANT);
				Matcher matcherTmp = patternTmp.matcher(varName);
				if (matcherTmp.matches()){
					//constant-string
					instruction = new TDeclaration(varName);
				}else{
					throw new Exception("Invalid name");
				}
			}else{
				throw new Exception("Error near VarDeclT");
			}
			
			
		}else if(line.equals("Collect")){
			instruction = new CollectInst();
			
		}else if(line.equals("HeapAnalyze")){
			instruction = new HeapAnalyzeInst();
			
		}else { // assignment
			
			String[] splittedLine = line.split("=");

			if(splittedLine.length == 2) {
				String lval = splittedLine[0];
				String rval = splittedLine[1];
				instruction = new AssignmentInst(lval.trim(), rval.trim());
			}else{
				throw new Exception("Unknwon instruction!");
			}

		}
		
		return instruction;
		
	}

}

